
from django.core.validators import RegexValidator
from django.db import models
from django.utils import timezone
from django.core import validators


# 振动传感器数据模型（对应数据库表）
class VibrationData(models.Model):
    # 时间戳字段（自动记录数据时间）
    # db_index=True 表示创建数据库索引
    timestamp = models.DateTimeField(default=timezone.now, db_index=True, verbose_name='记录时间')

    bearing_id = models.IntegerField(verbose_name='bearing_id', default=0)

    x_acc_rms = models.FloatField(verbose_name='x_acc_rms')
    y_acc_rms = models.FloatField(verbose_name='y_acc_rms')
    z_acc_rms = models.FloatField(verbose_name='z_acc_rms')

    x_v_rms = models.FloatField(verbose_name='x_v_rms')
    y_v_rms = models.FloatField(verbose_name='y_v_rms')
    z_v_rms = models.FloatField(verbose_name='z_v_rms')

    temperature = models.FloatField(verbose_name='temperature')


class VibrationAudio(models.Model):

    bearing_id = models.IntegerField(verbose_name='bearing_id', default=0)

    # 与振动数据的一对一关联（级联删除）
    vibration_data = models.OneToOneField(
        VibrationData,
        on_delete=models.CASCADE,
        related_name='audio_data',
        verbose_name='CorrespondingVibrationData'
    )

    audio_samples = models.JSONField(
        validators=[
            RegexValidator(
                regex=r'^$$\s*(\d+\s*,\s*){127}\d+\s*$$$',
                message='Must be a JSON array containing 128 integers (example: [2106,2105,...])'
            )
        ],
        verbose_name='VibrationAudioRawData',
    )

    # 新增：存储音频特征
    extracted_features = models.JSONField(
        default=dict,
        verbose_name='ExtractedAudioFeatures',
        help_text='存储从音频样本中提取的时域特征'
    )

    # 采样率HZ
    sample_rate = models.PositiveIntegerField(
        default=16000,
        verbose_name='SamplingRate'
    )

    # 记录时间
    timestamp = models.DateTimeField(
        auto_now_add=True,
        db_index=True,
        verbose_name='RecordTime'
    )

    def save(self, *args, **kwargs):
        # 如果audio_samples存在但extracted_features为空，则提取特征
        if self.audio_samples and not self.extracted_features:
            from .views import extract_time_features  # 避免循环导入
            self.extracted_features = extract_time_features(self.audio_samples)
        super().save(*args, **kwargs)


class BearingHealth(models.Model):
    STATUS_CHOICES = [
        ('normal', '正常'),
        ('early_warning', '早期预警'),
        ('maintenance_required', '需要维护'),
        ('immediate_action', '立即检修'),
    ]

    FAULT_TYPE_CHOICES = [
        ('unbalance', '不平衡'),
        ('misalignment', '不对中'),
        ('bearing_fault', '轴承故障'),
        ('resonance', '共振'),
        ('loose_part', '部件松动'),
    ]

    bearing_id = models.IntegerField(verbose_name='bearing_id', default=0)

    vibration_data = models.OneToOneField(
        VibrationData,
        on_delete=models.CASCADE,
        related_name='health_status',  # 反向关联名称（可通过振动数据查健康状态）
        verbose_name='AssociatedSensorData'
    )
    # 整体状态
    overall_status = models.CharField(
        max_length=20,
        choices=STATUS_CHOICES,
        default='normal',
        verbose_name='OverallState'
    )

    confidence_level = models.FloatField(
        default=0.0,
        validators=[
            validators.MinValueValidator(0.0),  # 最小值0.0
            validators.MaxValueValidator(1.0)  # 最大值1.0
        ],
        verbose_name='ConfidenceLevel'
    )
    # 主要故障类型
    primary_fault = models.CharField(
        max_length=20,
        choices=FAULT_TYPE_CHOICES,
        null=True,
        blank=True,
        verbose_name='PrimaryFaultTypes'
    )

    analysis_timestamp = models.DateTimeField(
        auto_now_add=True,
        verbose_name='AnalysisTime'
    )
    algorithm_version = models.CharField(
        max_length=20,
        default='v1.0',
        verbose_name='AnalysisAlgorithmVersion'
    )
